﻿using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using NiuPi.Database.Platform;
using SqlSugar;
using Furion;
using NiuPi.Tools;
using Furion.FriendlyException;
using NiuPi.Platform.Entity;

namespace NiuPi.Platform.Services
{
    /// <summary>
    /// 菜单路由模块
    /// </summary>
    [Route("api/platform/[controller]")]
    [ApiDescriptionSettings("platform")]
    public class MenuService : IDynamicApiController, ITransient
    {
        private readonly ILogger<MenuService> Logger;
        private readonly SqlSugarScope Db;
        public MenuService(ILogger<MenuService> _Logger, SqlSugarScope _Db)
        {
            Logger = _Logger;
            Db = _Db;
        }
        /// <summary>
        /// 根据父级ID获取菜单数据
        /// </summary>
        /// <param name="parentID"></param>
        /// <returns></returns>
        private async Task<List<MenuTree>> MenuList(long parentID)
        {
            List<MenuTree> menuTree = new List<MenuTree>();
            var menu = new List<Menu>();
            var node = new MenuTree();
            var result = await Db.Queryable<Menu>().Where(x => x.ParentID == parentID).OrderBy(x => x.Sort, OrderByType.Desc).ToListAsync();
            foreach (var info in result)
            {
                var children = await MenuList(info.Id);
                node = new MenuTree()
                {
                    Id = info.Id,
                    ParentID = info.ParentID,
                    Type = info.Type,
                    MenuName = info.MenuName,
                    RoutePath = info.RoutePath,
                    Permission = info.Permission,
                    AssemblyPath = info.AssemblyPath,
                    Icon = info.Icon,
                    Status = info.Status,
                };
                if (children.Count > 0)
                {
                    node.Children = children;
                }
                menuTree.Add(node);
            }
            return menuTree;
        }
        /// <summary>
        /// 获取菜单的前端路由数据
        /// </summary>
        /// <returns></returns>
        private async Task<List<RouteMenu>> RouteMenuTree()
        {
            var routes = new List<RouteMenu>();
            var menus = await MenuList(0);
            foreach (var info in menus)
            {
                var routeChildrents = new List<RouteMenuChild>();
                var route = new RouteMenu
                {
                    name = info.MenuName,
                    path = info.RoutePath,
                    component = info.RoutePath,
                    redirect = info.RoutePath == "/home" ? "" : info.RoutePath,
                    meta = new MenuMeta
                    {
                        title = info.MenuName,
                        icon = info.Icon,
                        auth = await RouteAuth(info.Id, true),
                        isAffix = info.RoutePath == "/home" ? true : false,
                        isKeepAlive = true,
                    },

                };
                var children = info.Children;
                foreach (var child in children)
                {
                    var routeChildren = new RouteMenuChild();
                    routeChildren.path = child.RoutePath;
                    routeChildren.name = child.RoutePath;
                    routeChildren.component = child.AssemblyPath;
                    routeChildren.meta.title = child.MenuName;
                    routeChildren.meta.icon = child.Icon;
                    routeChildren.meta.auth = await RouteAuth(child.Id, false);
                    routeChildren.meta.isKeepAlive = true;
                    routeChildrents.Add(routeChildren);
                }
                route.children = routeChildrents;
                routes.Add(route);
            }
            return routes;
        }
        /// <summary>
        /// 根据ID和是否顶级菜单，查询权限标识
        /// </summary>
        /// <param name="Id"></param>
        /// <param name="isTop"></param>
        /// <returns></returns>
        private async Task<string[]?> RouteAuth(long? Id, bool isTop)
        {
            var menus = new List<Menu>();
            var menu = new Menu();
            var permissions = new List<string>();
            var topMenu = Db.Queryable<Menu>().Where(x => x.Id == Id).OrderBy(x => x.Sort, OrderByType.Desc);
            if (isTop)
            {
                var permission = await topMenu.FirstAsync();
                permissions.Add(permission.Permission);
            }
            else
            {
                var notTopMenu = await topMenu.ToListAsync();
                foreach (var info in notTopMenu)
                {
                    permissions.Add(info.Permission);
                }
                permissions.Add(topMenu.First().Permission);
            }
            return permissions.Count > 0 ? permissions.ToArray() : null;
        }

        /// <summary>
        /// 添加目录/菜单/按钮
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> Add(Menu input)
        {
            //自动将前端参数映射到模型
            var model = input.Adapt<Menu>();
            if (Db.Queryable<Menu>().AnyAsync(x => x.Permission == input.Permission).Result) throw Oops.Oh("权限标识已存在！");
            var result = await Db.Insertable(model).ExecuteCommandAsync();
            if (result > 0)
            {
                return RestfulResult.Instance.OnSucceeded();
            }
            else
            {
                return RestfulResult.Instance.OnFailed();
            }
        }
        /// <summary>
        /// 编辑目录/菜单/按钮
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> Edit(Menu input)
        {
            //自动将前端参数映射到模型
            var model = input.Adapt<Menu>();
            var result = await Db.Updateable<Menu>().SetColumns(x => x.MenuName == input.MenuName).SetColumns(x => x.Icon == input.Icon).Where(o => o.Id == input.Id).ExecuteCommandAsync();
            if (result > 0)
            {
                return RestfulResult.Instance.OnSucceeded();
            }
            else
            {
                return RestfulResult.Instance.OnFailed();

            }
        }
        /// <summary>
        /// 删除目录/菜单/按钮
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> Del(int id)
        {
            var result = await Db.Deleteable<Menu>(id).ExecuteCommandAsync();
            if (result > 0)
            {
                return RestfulResult.Instance.OnSucceeded();
            }
            else
            {
                return RestfulResult.Instance.OnFailed();
            }
        }
        /// <summary>
        /// 根据ID查询菜单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<IActionResult> GetOne(int id)
        {
            var model = await Db.Queryable<Menu>().Where(x => x.Id == id).FirstAsync();
            if (model.Id > 0)
            {
                return RestfulResult.Instance.OnSucceeded(model);
            }
            else
            {
                return RestfulResult.Instance.OnFailed();
            }
        }
        /// <summary>
        /// 批量添加菜单
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> AddAll(Menu[] input)
        {
            //自动将前端参数映射到模型
            var model = input.Adapt<Menu[]>();
            var result = await Db.Insertable<Menu>(model).ExecuteCommandAsync();
            if (result > 0)
            {
                return RestfulResult.Instance.OnSucceeded();
            }
            else
            {
                return RestfulResult.Instance.OnFailed();
            }
        }
        /// <summary>
        /// 根据父级ID查询无限级Tree
        /// </summary>
        /// <param name="parentID"></param>
        /// <returns></returns>
        public async Task<IActionResult> GetMenuTree(long parentID)
        {
            var result = await MenuList(parentID);
            return RestfulResult.Instance.OnSucceeded(result);
        }
        /// <summary>
        /// 获取前端路由Tree菜单
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> GetRouteMenuTree()
        {
            var result = await RouteMenuTree();
            return RestfulResult.Instance.OnSucceeded(result);
        }
    }
}
